/**
 * 锥体 - L5
 * @author lonphy
 * @version 0.1
 */
(function(L5) {
	"use strict";
	const BANDS = 10;
	class Cone {
		/**
		 * 构造
		 * @param radius {Number} 底面半径
		 * @param height {Number} 锥体高度
		 * @param rb {Number} 圆面切分段数， 例如2 生成 3棱锥， n 生成 n+1棱锥
		 */
		constructor(radius, height, rb) {
			this.radius = radius || 1;
			this.height = height || 1;

			this.vertices = [];
			this.indices = [];
			this.materialLibrary = {};
			this.maters = [];

			this.rb = rb || BANDS;

			this.create();
		}

		/**
		 * 构造平面
		 */
		create() {
			var rb = this.rb,
				radius = this.radius,
				maxStep = rb+ 1,
				angleStep = 2*Math.PI/maxStep,
				uvStep = 1/maxStep,
				ss = maxStep+ 1,
				bottom = [], side = [],
				bottomIndices=[], sideIndices=[],
				ca, asin,acos, a,rc,rs,
				AB,AC,BC,NR;

			// 顶部尖
			side.push(0, this.height, 0);	// center pos
			side.push(0,1,0);		// normal
			side.push(0,0,0);		// uv

			// 底面圆心
			bottom.push(0,0, 0);	// center pos
			bottom.push(0,-1,0);		// normal
			bottom.push(0.5,0.5, 0);		// uv

			for (a = 0; a < maxStep; ++a) {
				// 当前角度XY
				ca = a * angleStep;
				asin = Math.sin(ca);
				acos = Math.cos(ca);
				rc = radius*acos;
				rs = radius*asin;

				bottom.push(rc, 0, rs);					// first pos
				bottom.push(0, -1, 0);											// normal
				bottom.push(0.5 - 0.5*acos, 0.5-0.5*asin, 0);						// uv
				bottomIndices.push(0, a+1, a+2);

				side.push(rc, 0, rs);
				AB = new L5.Vec3([rc, 0, rs]);
				AC = new L5.Vec3([0, this.height ,0]);
				BC = AB.clone().add(AC);
				NR = BC.cross(AB.cross(AC)).normalize();
				side.push(NR.x, NR.y, NR.z);		// TODO:这里计算错误.normal
				side.push(1, 1-a*uvStep, 0);		// uv

				sideIndices.push(ss, ss+a+2, ss+a+1);
			}

			bottomIndices[bottomIndices.length-1] = 1;
			sideIndices[sideIndices.length-2] = ss+1;


			this.vertices = bottom.concat(side);
			this.indices = bottomIndices.concat(sideIndices);
		}

		setMaterial(name, mater) {
			this.materialLibrary[name] = mater;
			this.maters.push(name);
		}

		getMesh() {
			return {
				vertices: this.vertices.slice(),
				indices: this.indices.slice(),
				materialLibrary: this.materialLibrary,
				maters: this.maters.slice(),
				hasIndex: true
			};
		}
	}

	L5.Geometry.Cone = Cone;
})(window.L5);